2009-11-30 9 views
1
import java_cup.runtime.*; 
import java.io.*; 
import java.util.*; 

/* Preliminaries to set up and use the scanner. */ 

parser code {: 
     SMPLLexer lexer; 


     public SMPLParser (SMPLLexer lex) { 
      super(lex); 
      lexer = lex; 
     } 

     public void report_error(String message, Object info) { 
      System.err.println(message + info); 
     } 

     public void syntax_error(Symbol cur_token) { 
      System.err.print("Line " + lexer.getLine() + 
        " near char " + lexer.getChar() + ": "); 
      report_error("Syntax error while reading: ", cur_token); 
      System.err.println ("Last token read is " + 
        lexer.getText()); 
     } 

     public void unrecover_syntax_error(Symbol cur_token) { 
      System.err.println("Line " + lexer.getLine() + 
         "near char " + lexer.getChar() + ": "); 
         syntax_error(cur_token); 
        } 

     :}; 


/* Terminals (tokens returned by the scanner). */ 

// special symbols 
terminal LBRACKET, RBRACKET, LCBRACKET, RCBRACKET, LPAREN, RPAREN, /* LBRACE, RBRACE, */ SEMI, ASSIGN, COLON, COMMA, EMPTYLIST; /*, DOT, AT; */ 

// opeartors: base 
terminal PAIR, CAR, CDR, LIST, SIZE, SUBSTRING, PROC, CALL, LAZY, LET, BE, DEFINE, PRINT, PRINTLN, READ, READINT; 

// operators: equality 
terminal PAIREQ, EQV, EQUAL; 

// commands: commands 
terminal CLEAR, SETBGCOLOR, SETFGCOLOR, PATH, CPATH, PT, CANVAS, RECT, CIRCLE; 

// commands: conditional 
terminal IF, THEN, ELSE, REPEAT; /* , CASE, WHILE, FOR, TRUE, FALSE; */ 

// operators: arithmetic 
terminal PLUS, MINUS, MUL, DIV, MOD, EXPT; 

// operators: relational 
terminal LT, GT, EQ, LTEQ, GTEQ, NOTEQ; 

//operators: logical 
terminal AND, OR, NOT; 

// operators: bitwise 
terminal BITAND, BITOR, INVERT; 

// terminals with values 
terminal Integer INTEGER; 
terminal String STRING; 
terminal String VAR; 
terminal String ID; 

/* Non terminals */ 
// (You're on your own for the IR classes) 
non terminal IRProgram program; 
non terminal IRCmd statement; 
non terminal IRExp expression; 
non terminal IRExp arithExp; 
non terminal IRExp relExp; 
non terminal IRExp logExp; 
non terminal IRExp bitExp; 
non terminal IRExp term; 
non terminal IRExp expt; 
non terminal IRExp factor; 

non terminal ArrayList statementList; 
non terminal IRCmdSeq cmdList; 

non terminal ArrayList varList; 
non terminal ArrayList expList; 
non terminal ArrayList assList; 

// non terminal ArrayList sequence; 
non terminal empty; 


/* Precedence */ 

precedence left OR; 
precedence left AND; 
precedence left NOT; 
precedence left EQ, GT, LT, LTEQ, GTEQ, NOTEQ; 
precedence left BITAND, BITOR; 
precedence left PLUS, MINUS; 
precedence left MUL, DIV, MOD; 
precedence right INVERT; 

/* Grammar rules */ 

start with program; 

program ::= statementList:lst SEMI {: RESULT = new IRProgram(lst); :} | 
         statementList:lst {: RESULT = new IRProgram(lst); :} | 
         STRING:str {: RESULT = new IRCmdSeq(lst); :}       

; 

cmdList ::= statementList:lst {: RESULT = new IRCmdSeq(lst); :}; 

statementList ::= statementList:lst statement:s {:lst.add(s); RESULT = lst; :} | 
        empty {: RESULT = new ArrayList(); :}; 

statement ::= 

    PAIR statement:s1 statement:s2 {: RESULT = new IRPAIR(s1,s2); :} | 

    PAIREQ LPAREN PAIR:p RPAREN {: new IRPAIR(p); :} | 

    CAR varList:s1 {: RESULT = new IRCAR(s1); :} | 

    CDR varList:s1 {: RESULT = new IRCDR(s1); :} | 

    EQV expression:e1 expression:e2 {: RESULT = new IREQV(e1,e2); :} | 

    EQUAL expression:e1 expression:e2 {: RESULT = new IREQUAL(e1,e2); :} | 

    SUBSTRING STRING:v arithExp:e1 arithExp:e2 {: RESULT = new IRSUBSTR(v,e1,e2); :} | 

    SIZE LIST:n {: RESULT = new IRSIZE(n); :} | 

    PROC ID:n cmdList:e {: RESULT = new IRPROC(n,e); :} | 

    CALL expression:e1 cmdList:body {: RESULT = new IRCALL(e1,body); :} | 

    LAZY expression:e1 {: RESULT = new IRLAZY(e1); :} | 

    DEFINE ID:pred expression:e1 {: RESULT = new IRDEFINE(pred,e1); :} | 

    LIST LPAREN varList:s RPAREN {: RESULT = new IRLIST(s); :} | 

    LIST LPAREN LBRACKET varList:s RBRACKET RPAREN {: RESULT = new IRLIST(s); :} | 

    LBRACKET varList:s RBRACKET {: RESULT = new IRLIST(s); :} | 

    LCBRACKET varList:s RCBRACKET {: RESULT = new IRLIST(s); :} | 

    //LBRACKET sequence:s RBRACKET {: RESULT = new IRLIST(s); :} | 

    ID:n ASSIGN expression:n {: RESULT = new IRASSIGN(n); :} | 

    ID:n ASSIGN expList:n {: RESULT = new IRASSIGN(n); :} | 

    LET ID:n BE expression:e {: RESULT = new IRLET(n,e); :} | 


    /** Graphic Components **/ 
    CLEAR {: RESULT = new IRCmdClear(); :} | 

    CANVAS LPAREN arithExp:e1 arithExp:e2 RPAREN {: RESULT = new IRCmdCanvas(e1,e2); :} | 

    PT LPAREN arithExp:e1 arithExp:e2 RPAREN {: RESULT = new IRCmdPT(e1,e2); :} | 

    PATH LPAREN arithExp:e1 arithExp:e2 RPAREN {: RESULT = new IRCmdPath(e1,e2); :} | 

    CIRCLE LPAREN arithExp:e1 arithExp:e2 arithExp:e3 RPAREN {: RESULT = new IRCmdCircle(e1,e2,e3); :} | 

    CPATH LPAREN arithExp:e1 arithExp:e2 RPAREN {: RESULT = new IRCmdCPath(e1,e2); :} | 

    SETFGCOLOR LPAREN arithExp:e1 arithExp:e2 arithExp:e3 RPAREN {: RESULT = new IRCmdSetFG(e1,e2,e3); :} | 

    SETBGCOLOR LPAREN arithExp:e1 arithExp:e2 arithExp:e3 RPAREN {: RESULT = new IRCmdSetBG(e1,e2,e3); :} | 

    RECT LPAREN arithExp:e1 arithExp:e2 arithExp:e3 RPAREN {: RESULT = new IRCmdRect(e1,e2,e3); :} | 


    //conditionals 

    IF expression:pred THEN cmdList:cond ELSE cmdList:alt {: RESULT = new IRCmdIf(pred, cond, alt); :} | 

    // TODO CASE LBRACE expList RBRACE 

    PRINT cmdList:e1 {: RESULT = new IRPRINT(e1); :} | 

    PRINTLN cmdList:e1 {: RESULT = new IRPRINTLN(e1); :} | 

    READ STRING:n {: RESULT = new IRREAD(n); :} | 

    READINT STRING:n {: new IRREADINT(n);:} | 

    //iteration 
    REPEAT arithExp:count cmdList:body {: RESULT = new IRCmdRepeat(count, body); :} | 

    EMPTYLIST {: RESULT = new ArrayList(); :} 

    ; 

varList ::= 
      varList:lst COMMA expression:i COLON PROC:p {: lst.add(new IRVarList(i,p)); RESULT = lst; :} | 
      varList:lst COMMA expression:i {: lst.add(i); RESULT = lst; :} | 
     empty {: RESULT = new ArrayList(); :}; 

// list of expressions 
expList ::= 
      expList:lst COMMA expression:v {: lst.add(v); RESULT = lst; :} | 
      expList:lst expression:v {: lst.add(v); RESULT = lst; :} | 
     empty {: RESULT = new ArrayList(); :}; 

/* 
sequence ::= 
      sequence:s expression:e COMMA {: RESULT = s.add(e); } | 
      sequence:s expression:e {: RESULT = s.add(e); } | 
      empty {: RESULT = new ArrayList(); :}; 
*/   


/* I'm giving you the expression hierarchy already done. (Am I not nice?) */ 
expression ::= 

     arithExp:ae {: RESULT = ae; :} | 
     bitExp:be {: RESULT = be; :} | 
     relExp:re {: RESULT = re; :} | 
     logExp:le {: RESULT = le; :}; 

     //relational expressions 
relExp ::= 

     //relational ops 
     arithExp:e1 EQ arithExp:e2 {: RESULT = new IRExpEq(e1, e2); :} | 
     arithExp:e1 LT arithExp:e2 {: RESULT = new IRExpLt(e1, e2); :} | 
     arithExp:e1 GT arithExp:e2 {: RESULT = new IRExpGt(e1, e2); :} | 
     arithExp:e1 LTEQ arithExp:e2 {: RESULT = new IRExpLtEq(e1, e2); :} | 
     arithExp:e1 GTEQ arithExp:e2 {: RESULT = new IRExpGtEq(e1, e2); :} | 
     arithExp:e1 NOTEQ arithExp:e2 {: RESULT = new IRExpNotEq(e1, e2); :} 
     ; 

logExp ::= 

     //logical ops 
     arithExp:e1 AND arithExp:e2 {: RESULT = new IRExpAnd(e1, e2); :} | 
     arithExp:e1 OR arithExp:e2 {: RESULT = new IRExpOr(e1, e2); :} | 
     arithExp:e1 NOT arithExp:e2 {: RESULT = new IRExpNot(e1, e2); :} 
     ; 

bitExp ::= 

     //bitwise ops 
     arithExp:e1 BITAND arithExp:e2 {: RESULT = new IRExpBitAnd(e1, e2); :} | 
     arithExp:e1 BITOR arithExp:e2 {: RESULT = new IRExpBitOr(e1, e2); :} | 
     arithExp:e1 INVERT arithExp:e2 {: RESULT = new IRExpIvert(e1, e2); :} 
     ; 

     //arithmetic expressions 
arithExp ::= 

     arithExp:e PLUS term:t {: RESULT = new IRExpAdd(e, t); :} | 
     arithExp:e MINUS term:t {: RESULT = new IRExpSub(e, t); :} | 
     term:t {: RESULT = t; :} 

     ; 

term ::= 

    term:t MUL expt:x {: RESULT = new IRExpMul(t, x); :} | 
    term:t MOD expt:x {: RESULT = new IRExpMod(t, x); :} | 
    term:t DIV expt:x {: RESULT = new IRExpDiv(t, x); :} | 
    expt:x {: RESULT = x; :} 

    ; 

expt ::= 
    expt:x EXPT factor:f {: RESULT = new IRExpExpt(x, f); :} | 
    factor:f {: RESULT = f; :} 

    ; 

factor ::= 
    INTEGER:n {: RESULT = new IRExpConst(n.intValue()); :} | 
    VAR:var {: RESULT = new IRExpVar(var); :} | 
    STRING:n {: RESULT = new IRExpString(n); :} | 
    LPAREN arithExp:e RPAREN {: RESULT = e; :} 
    // LBRACE arithExp:e RBRACE {: RESULT = e :} 
     ; 

empty ::=; 

어떤 변화를 가져 오기 줄일 수 있습니다. 사람이 바로 빛 PLZ에 나를 인도 할 수 있습니까?시프트 내가 :-(를 구축하기 위해 노력하고있어 간단한 언어이 문법을 제압하려고 갈등을 줄이기/갈등

답변

2

나는 38 S/R 충돌을 얻을 후 너무 많은 경고 오류? "일부 변화는/충돌을 감소".

은 아마도 난 그냥 첫 번째를 분석해야합니다.

> Warning : *** Shift/Reduce conflict 
> found in state #106 between cmdList 
> ::= statementList (*) and  
> statement ::= (*) LBRACKET varList 
> RBRACKET under symbol LBRACKET 
> Resolved in favor of shifting. 

을 그래서, 모습 진술은 가능할 수있다. 그 뒤에는 [something]이 계속됩니다. 따라서 파서는 파싱 (shift) 또는 파싱 (para)을 유지할지 여부를 이미 알지 못합니다.

이것은 LALR (1) 파서의 시프트/감소 충돌이 반드시 오류가되는 것은 아닌 좋은 예입니다. 일반적으로 교대 작업을 원하므로 기본 작업은 완벽하게 합리적이며 충돌은 분명한 의미가없는 순수한 기술적 모호성입니다.

"내 문법이 '...이 구문을 분석하지 않습니다.'와 같은 질문을하는 것이 더 도움이 될 수 있습니다. 왜 안 되니?"

+0

안녕하세요. 통찰력에 감사드립니다. :) u는이 plz를 고치면서 나를 설명하고 도와 줄 수있다. – ferronrsmith

+0

무엇을 고치고 있습니까? 충돌이 반드시 오류인지 여부는 알 수 없습니다. 컵에는 특정 개수의 S/R 충돌을 예상하는 방법이있을 것입니다. 문서를 읽고, 큰 숫자를주고, 문법을 실행하십시오. 그것이 할 수 있고 할 수없는 것을보십시오. 실제 문제가있는 경우 특정 질문을하십시오. 재미있어! – DigitalRoss

+0

이 경우 PROC 문으로 인해 문제가 발생합니다. 궁극적으로 (예를 들어) PROC id 을 처리 할 때 구문 분석기는 PROC 본문에 을 포함 시키거나 독립 선언문으로 처리해야합니다. 여기서 모호한 문법을 ​​사용하고 있으며, 모호하지 않은 문법을 지정할 수 있도록 언어를 변경하는 것이 수정되었습니다. –