用于解析 C 源代码文件并从中获取函数的 Antlr 语法



我写了一个Antlr语法,用于解析C源代码文件中的函数:

grammar newCfunctions;
options
{
    language = CSharp;
}
@parser::namespace { Generated }
@lexer::namespace  { Generated }
func
    :function+ { Console.WriteLine("hello"); } //this is for debugging
    ;
NAME
    :[a-zA-Z]+[a-zA-Z0-9]*
    ;
TYPENAME
    :   'void'
    |   [a-zA-Z]+
    |   'char'
    |   'short'
    |   'int'
    |   'long'
    |   'float'
    |   'double'
    |   'signed'
    |   'unsigned'
    |   '_Bool'
    |   '_Complex'
    |   '__m128'
    |   '__m128d'
    |   '__m128i'
    |   NAME
    ;
arguments
    :   (TYPENAME NAME)*
    ;
Newline
    :   'r'? 'n' ;
FUNCTIONBODY
    :   ([a-zA-Z0-9]|Newline)*;
function 
    :   TYPENAME ' ' NAME '(' arguments ')' ' '? Newline? '{' FUNCTIONBODY '}' Newline?
    ;

我生成了 C# 文件并将它们包含在测试项目中。它的主要功能:

            try
            {
                AntlrInputStream input = new AntlrInputStream(Console.In);
                newCfunctionsLexer lexer = new newCfunctionsLexer(input);
                CommonTokenStream tokens = new CommonTokenStream(lexer);
                newCfunctionsParser parser = new newCfunctionsParser(tokens);
                parser.func();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            Console.ReadKey();

当我写"void foo(int a){return a;}"时,它给了我ann错误:"行1:0不匹配的输入'void'期望TYPENAME"。请帮我这个语法!我在互联网上看到了C语法,但它有800+行,我不知道如何处理它。如果你知道,如何使用它,请给我。谢谢!

正如已经说过NAME规则应该放在TYPENAME规则之后。此外,词素TYPENAME不应包含词素NAME[a-zA-Z]+

所以,最后的版本:

grammar newCfunctions;
options
{
    language = CSharp;
}
@parser::namespace { Generated }
@lexer::namespace  { Generated }
func
    : function+ { Console.WriteLine("hello"); } //this is for debugging
    ;
function 
    : typename ' ' NAME '(' arguments ')' ' '? Newline? '{' functionBody '}' Newline?
    ;
arguments
    : (typename NAME)*
    ;
typename
    : TYPENAME
    | NAME
    ;
functionBody
    : (TYPENAME | NAME | Newline)*
    ;
TYPENAME
    :   'void'
    |   'char'
    |   'short'
    |   'int'
    |   'long'
    |   'float'
    |   'double'
    |   'signed'
    |   'unsigned'
    |   '_Bool'
    |   '_Complex'
    |   '__m128'
    |   '__m128d'
    |   '__m128i'
    ;
NAME
    : [a-zA-Z]+ [a-zA-Z0-9]*
    ;
Newline
    :   'r'? 'n' ;

此外,我建议在解析过程中忽略换行符和空格的通道。

相关内容

  • 没有找到相关文章

最新更新