2017-07-12 2 views
0

私はAntlr4で簡単なQBasic文法を書こうとしています。そして、 'Else-If'ループは正しく動作しません。は、THENの後に自動的にassigncommandに変換されます。文法を見直すことができますか?改善はありますか?正規表現でstringの書き方を文法パーサの提案(ANTLR)

。(また、キリル文字のアルファベットで)

私は、これらのキーワード('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; 

答えて

0

、私は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; 
    } 

を私は彼のMu言語のバートKiersの優れた実装からMuValueアイデアを借りました。彼のプロジェクトの素晴らしいアイデアがたくさんあります。