繁体   English   中英

语法解析器建议(ANTLR)

[英]Grammar parser suggestion (ANTLR)

好吧,我正在尝试在Antlr4上编写一个简单的QBasic语法。 而且“ Else-If”循环将无法正常工作,它将在THEN之后自动转换为assigncommand 您能复习一下我的语法吗,有什么改进吗?

如何以正则表达式编写string (也包含西里尔字母)

我应该写这些关键词( 'PRINT' 'IF' )吗? 或使用词法分析器(如..PRINTKEY; PRINTKEY : 'PRINT'

grammar Hello3;

// AssignCommand; MainCommand; FlowCommand
prog : (assigncommand | maincommand | flowcommand)+;

// AssignInt; AssignString
// MyAge = PreviousAge + 1
// MyName$ = FirstName$ + MiddleName$ + LastName$
assigncommand : assignint | assignstring;
assignint : IDINT '=' (IDINT | INT) (OPERATORMATH (IDINT | INT))* '\n'+;
assignstring : IDSTRING '=' (IDSTRING | STRING) ('+' (IDSTRING | STRING))* '\n'+;

//PrintCommand, InputCommand
//PRINT MyName$, MyAge, "Hello", 123
//INPUT "What is your name?", yourname$
//(or)INPUT yourname$ 
maincommand : printcommand | inputcommand;
printcommand : 'PRINT' (',' (IDINT | IDSTRING | STRING | INT))+ '\n'+;
inputcommand : 'INPUT' (IDINT | IDSTRING | STRING)? ',' (IDINT | IDSTRING) '\n'+;


//If-ElseFlow; WhileFlow
//If-Else-Add; Else-Add
//
//IF a > 3 THEN
//PRINT a
//a = a -1
//ELSE IF a = 1 THEN
//b = a
//END IF
//
//WHILE a > 3
//a = a - 1
//PRINT a
//WEND
flowcommand : ifelseflow | whileflow;
ifelseflow : 'IF' conditionflow 'THEN' '\n' ifelseadd* elseadd* 'END' 'IF' '\n'+;
whileflow : 'WHILE' conditionflow '\n' (assigncommand | maincommand | flowcommand)*  'WEND' '\n'+;

conditionflow : ((INT | IDINT) OPERATORBOOL (INT | IDINT)) | ((STRING | IDSTRING) '=' (STRING | IDSTRING));
ifelseadd : 'ELSEIF' conditionflow 'THEN' '\n' ((assigncommand | maincommand | flowcommand) '\n')+;
elseadd : 'ELSE' '\n' ((assigncommand | maincommand | flowcommand) '\n')+;

//Lexers
INT : [0-9]+;
STRING : '"' [a-zA-Z\u0400-\u04FF\0-9' ''?'':']+ '"'; 
IDINT : [a-zA-Z]([a-zA-Z0-9]*);       //MyAge
IDSTRING : [a-zA-Z]([a-zA-Z0-9]*)'$';  //MyName$ 
OPERATORMATH : '+'|'-'|'*'|'/';
OPERATORBOOL : '='|'>'|'<'|'>='|'<=';
WS : [ \t\r]+ -> skip;

像您一样,我发现以类似BASIC的语言实现if..else构造的实现确实是一项挑战。 我在网上找到了一些很好的资源。 请看一下我的语法片段:

ifstmt
:   IF condition_block (ELSE IF condition_block)* (ELSE stmt_block)?
;

condition_block
:   expr stmt_block
;

stmt_block
:   OBRACE statement+ CBRACE
|   statement
;

和我的实现(以C#访问者模式):

    public override MuValue VisitIfstmt(LISBASICParser.IfstmtContext context)
    {
        LISBASICParser.Condition_blockContext[] conditions = context.condition_block();
        bool evaluatedBlock = false;
        foreach (LISBASICParser.Condition_blockContext condition in conditions)
        {
            MuValue evaluated = Visit(condition.expr());
            if (evaluated.AsBoolean())
            {
                evaluatedBlock = true;
                Visit(condition.stmt_block());
                break;
            }
        }
        if (!evaluatedBlock && context.stmt_block() != null)
        {
            Visit(context.stmt_block());
        }
        return MuValue.Void;
    }

我从Bart MuValueMu语言的出色实现中借鉴了MuValue思想。 在他的那个项目中有很多很棒的主意。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM