ANTLR4(十) 内嵌代码之计算器

写在之前

采用访问器的计算器

语法文件:

grammar Expr; 

prog:   stat+ ;

stat:   expr NEWLINE                
    |   ID '=' expr NEWLINE         
    |   CLEAR NEWLINE               
    |   NEWLINE                     
    ;

expr:   expr op=('*'|'/') expr      
    |   expr op=('+'|'-') expr      
    |   INT                         
    |   ID                          
    |   '(' expr ')'                
    ;

MUL :   '*' ; 
DIV :   '/' ;
ADD :   '+' ;
SUB :   '-' ;

ID  :   [a-zA-Z]+ ;      // match identifiers
INT :   [0-9]+ ;         // match integers
NEWLINE:'\r'? '\n' ;     // return newlines to parser (is end-statement signal)
WS  :   [ \t]+ -> skip ; // toss out whitespace

自定义Visitor:

//EvalVistor.java
import java.util.HashMap;
import java.util.Map;

public class EvalVisitor extends LabeledExprBaseVisitor<Integer> {
   
    /** "memory" for our calculator; variable/value pairs go here */
    Map<String, Integer> memory = new HashMap<String, Integer>();

    /** ID '=' expr NEWLINE */
    @Override
    public Integer visitAssign(LabeledExprParser.AssignContext ctx) {
   
        String id = ctx.ID().getText();  // id is left-hand side of '='
        int value = visit(ctx.expr());   // compute value of expression on right
        memory.put(id, value);           // store it in our memory
        return value;
    }

    /** expr NEWLINE */
    @Override
    
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ANTLR4 可以用来解析 C 代码,但是需要先编写好 C 语言的词法和语法规则。你可以使用 ANTLR4 提供的 C 语言语法规范作为参考,该语法规范定义了 C 语言的词法结构和语法结构。 具体来说,你需要使用 ANTLR4 编写 C 语言的词法规则和语法规则。词法规则用来将 C 代码分解成一个个词法单元(Token),语法规则用来将 Token 组合成一个抽象语法树(AST)。 下面是一个简单的示例,演示如何使用 ANTLR4 解析 C 代码: 1. 编写 C 语言的词法规则和语法规则(以 C99 标准为例): ``` grammar C99; compilationUnit : externalDeclaration+ ; externalDeclaration : functionDefinition | declaration ; functionDefinition : declarationSpecifiers declarator declarationList? compoundStatement ; declaration : declarationSpecifiers (initDeclaratorList)? ';' ; declarationSpecifiers : (storageClassSpecifier | typeSpecifier | typeQualifier)* ; initDeclaratorList : initDeclarator (',' initDeclarator)* ; initDeclarator : declarator ('=' initializer)? ; declarator : pointer? directDeclarator ; pointer : '*' typeQualifier* pointer? ; directDeclarator : identifier | '(' declarator ')' | directDeclarator '[' constantExpression? ']' ; typeQualifier : 'const' | 'volatile' ; typeSpecifier : 'void' | 'char' | 'short' | 'int' | 'long' | 'float' | 'double' | 'signed' | 'unsigned' | structOrUnionSpecifier | enumSpecifier | typedefName ; structOrUnionSpecifier : ('struct' | 'union') identifier? '{' structDeclaration* '}' ; structDeclaration : specifierQualifierList structDeclaratorList? ';' ; specifierQualifierList : (typeSpecifier | typeQualifier)+ ; structDeclaratorList : structDeclarator (',' structDeclarator)* ; structDeclarator : declarator? (':' constantExpression)? ; enumSpecifier : 'enum' identifier? '{' enumeratorList? '}' ; enumeratorList : enumerator (',' enumerator)* ; enumerator : identifier ('=' constantExpression)? ; typedefName : identifier ; initializer : assignmentExpression | '{' initializerList '}' | '{' initializerList ',' '}' ; initializerList : initializer (',' initializer)* ; statement : labeledStatement | compoundStatement | expressionStatement | selectionStatement | iterationStatement | jumpStatement ; labeledStatement : identifier ':' statement | 'case' constantExpression ':' statement | 'default' ':' statement ; compoundStatement : '{' (declaration | statement)* '}' ; expressionStatement : expression? ';' ; selectionStatement : 'if' '(' expression ')' statement ('else' statement)? | 'switch' '(' expression ')' statement ; iterationStatement : 'while' '(' expression ')' statement | 'do' statement 'while' '(' expression ')' | 'for' '(' expressionStatement expressionStatement? ')' statement ; jumpStatement : 'goto' identifier ';' | 'continue' ';' | 'break' ';' | 'return' expression? ';' ; expression : assignmentExpression (',' assignmentExpression)* ; assignmentExpression : conditionalExpression | unaryExpression assignmentOperator assignmentExpression ; conditionalExpression : logicalOrExpression ('?' expression ':' conditionalExpression)? ; logicalOrExpression : logicalAndExpression ('||' logicalAndExpression)* ; logicalAndExpression : inclusiveOrExpression ('&&' inclusiveOrExpression)* ; inclusiveOrExpression : exclusiveOrExpression ('|' exclusiveOrExpression)* ; exclusiveOrExpression : andExpression ('^' andExpression)* ; andExpression : equalityExpression ('&' equalityExpression)* ; equalityExpression : relationalExpression (('==' | '!=') relationalExpression)* ; relationalExpression : shiftExpression (('<' | '>' | '<=' | '>=') shiftExpression)* ; shiftExpression : additiveExpression (('<<' | '>>') additiveExpression)* ; additiveExpression : multiplicativeExpression (('+' | '-') multiplicativeExpression)* ; multiplicativeExpression : castExpression (('*' | '/' | '%') castExpression)* ; castExpression : '(' typeName ')' castExpression | unaryExpression ; unaryExpression : postfixExpression | ('++' | '--') unaryExpression | unaryOperator castExpression | sizeof unaryExpression | sizeof '(' typeName ')' ; postfixExpression : primaryExpression ( '[' expression ']' | '(' argumentExpressionList? ')' | '.' identifier | '->' identifier | '++' | '--' )* ; argumentExpressionList : assignmentExpression (',' assignmentExpression)* ; primaryExpression : identifier | constant | stringLiteral | '(' expression ')' ; constant : integerConstant | floatingConstant | enumerationConstant ; integerConstant : decimalConstant | octalConstant | hexadecimalConstant ; decimalConstant : ('0' | nonZeroDigit digit* ) ; octalConstant : '0' octalDigit* ; hexadecimalConstant : '0x' hexDigit+ ; floatingConstant : decimalFloatingConstant | hexadecimalFloatingConstant ; decimalFloatingConstant : fraction | exponent | fraction exponent ; fraction : digit+ '.' digit* ; exponent : ('e' | 'E') ('+' | '-')? digit+ ; hexadecimalFloatingConstant : hexadecimalPrefix hexFraction binaryExponent | hexadecimalPrefix hexadecimalDigit+ binaryExponent ; hexPrefix : ('0x' | '0X') ; hexFraction : hexadecimalDigit* '.' hexadecimalDigit+ | hexadecimalDigit+ '.' ; binaryExponent : ('p' | 'P') ('+' | '-')? digit+ ; enumerationConstant : identifier ; identifier : [a-zA-Z_] [a-zA-Z_0-9]* ; stringLiteral : '"' [^"\n]* '"' ; constantExpression : conditionalExpression ; typeName : specifierQualifierList abstractDeclarator? ; abstractDeclarator : pointer? directAbstractDeclarator ; directAbstractDeclarator : '(' abstractDeclarator ')' | '[' '*'? ']' | '[' directAbstractDeclarator ']' '[' assignmentExpression? ']' | '(' parameterTypeList? ')' ; parameterTypeList : parameterList (',' '...')? ; parameterList : parameterDeclaration (',' parameterDeclaration)* ; parameterDeclaration : declarationSpecifiers declarator | declarationSpecifiers abstractDeclarator? ; ``` 2. 使用 ANTLR4 生成 C 解析器的代码: ``` antlr4 C99.g4 javac C99*.java ``` 3. 编写一个 Java 类来读取 C 代码文件并解析: ``` import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.tree.*; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class CParser { public static void main(String[] args) throws IOException { String inputFile = null; if (args.length > 0) inputFile = args[0]; InputStream is = System.in; if (inputFile != null) is = new FileInputStream(inputFile); CharStream input = CharStreams.fromStream(is); CLexer lexer = new CLexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); C99Parser parser = new C99Parser(tokens); ParseTree tree = parser.compilationUnit(); // 解析 C 代码文件 System.out.println(tree.toStringTree(parser)); } } ``` 4. 运行 Java 程序来解析 C 代码文件: ``` java CParser test.c ``` 其中,`test.c` 是需要解析的 C 代码文件。 这样,就可以使用 ANTLR4 解析 C 代码了。需要注意的是,ANTLR4 生成的解析器只能解析语法正确的 C 代码,如果 C 代码存在语法错误,解析器将会抛出异常。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值