Создание парсеров на основе GPLEX+GPPG — различия между версиями
Материал из Вики ИТ мехмата ЮФУ
Admin (обсуждение | вклад) |
Admin (обсуждение | вклад) (Отмена правки 4386 участника Admin (обсуждение)) |
||
Строка 3: | Строка 3: | ||
[http://pascalabc.net/downloads/CompilerConstruction/SimplePas0.zip Комплект разработчика парсеров] | [http://pascalabc.net/downloads/CompilerConstruction/SimplePas0.zip Комплект разработчика парсеров] | ||
− | + | SimpleLex.lex | |
− | <pre>%namespace | + | <pre>%namespace LexScanner |
− | |||
− | |||
− | |||
Alpha [a-zA-Z_] | Alpha [a-zA-Z_] | ||
Строка 19: | Строка 16: | ||
":=" { return (int)Tokens.ASSIGN; } | ":=" { return (int)Tokens.ASSIGN; } | ||
";" { return (int)Tokens.SEMICOLON; } | ";" { return (int)Tokens.SEMICOLON; } | ||
− | |||
− | |||
− | |||
{ID} { | {ID} { | ||
Строка 34: | Строка 28: | ||
return (int)Tokens.INTNUM; | return (int)Tokens.INTNUM; | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
%% | %% | ||
Строка 60: | Строка 50: | ||
} | } | ||
− | } | + | }</pre> |
+ | |||
+ | |||
+ | |||
+ | |||
+ | ===SimpleYacc.yacc=== | ||
+ | |||
+ | <pre>%{ | ||
+ | // Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg | ||
+ | public ProgrNode root; // Корневой узел синтаксического дерева | ||
+ | public Parser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { } | ||
+ | %} | ||
+ | |||
+ | %output = SimpleYacc.cs | ||
+ | |||
+ | %union { | ||
+ | public double dVal; | ||
+ | public int iVal; | ||
+ | public string sVal; | ||
+ | public Node nVal; | ||
+ | public BlockNode blVal; | ||
+ | public ProgrNode prVal; | ||
+ | } | ||
+ | |||
+ | %using System.IO; | ||
+ | %using ProgramTree; | ||
+ | |||
+ | %namespace SimpleParser | ||
+ | |||
+ | %start progr | ||
+ | |||
+ | %token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON | ||
+ | %token <iVal> INTNUM | ||
+ | %token <sVal> ID | ||
+ | |||
+ | %type <nVal> expr assign st comp cycl ident | ||
+ | %type <blVal> stlist comp | ||
+ | %type <prVal> progr | ||
+ | |||
+ | %% | ||
+ | |||
+ | progr : stlist { root = new ProgrNode($1); } | ||
+ | ; | ||
+ | |||
+ | stlist : st | ||
+ | { | ||
+ | $$ = new BlockNode($1 as StatementNode); | ||
+ | } | ||
+ | | stlist SEMICOLON st | ||
+ | { | ||
+ | $1.Add($3 as StatementNode); | ||
+ | $$ = $1; | ||
+ | } | ||
+ | ; | ||
+ | |||
+ | st : assign { $$ = $1; } | ||
+ | | comp { $$ = $1; } | ||
+ | | cycl { $$ = $1; } | ||
+ | ; | ||
+ | |||
+ | ident : ID { $$ = new IdNode($1); } | ||
+ | ; | ||
+ | |||
+ | assign : ident ASSIGN expr { $$ = new AssignNode($1 as IdNode,$3 as ExprNode,0); } | ||
+ | ; | ||
+ | |||
+ | expr : ident { $$ = $1 as IdNode; } | ||
+ | | INTNUM { $$ = new NumNode($1); } | ||
+ | ; | ||
+ | |||
+ | comp : BEGIN stlist END { $$ = $2; } | ||
+ | ; | ||
+ | |||
+ | cycl : CYCLE expr st { $$ = new CycleNode($2 as ExprNode,$3 as StatementNode); } | ||
+ | ; | ||
+ | |||
+ | %% | ||
</pre> | </pre> |
Версия 10:01, 9 мая 2012
Комплект разработчика парсеров
SimpleLex.lex
%namespace LexScanner Alpha [a-zA-Z_] INTNUM [0-9]+ REALNUM {INTNUM}\.{INTNUM} ID [a-zA-Z_][a-zA-Z0-9_]* %% ":=" { return (int)Tokens.ASSIGN; } ";" { return (int)Tokens.SEMICOLON; } {ID} { int res = ScannerHelper.GetIDToken(yytext); if (res == (int)Tokens.ID) yylval.sVal = yytext; return res; } {INTNUM} { yylval.iVal = int.Parse(yytext); return (int)Tokens.INTNUM; } %% class ScannerHelper { private static Dictionary<string,int> keywords; static ScannerHelper() { keywords = new Dictionary<string,int>(); keywords.Add("begin",(int)Tokens.BEGIN); keywords.Add("end",(int)Tokens.END); keywords.Add("cycle",(int)Tokens.CYCLE); } public static int GetIDToken(string s) { if (keywords.ContainsKey(s.ToLower())) return keywords[s]; else return (int)Tokens.ID; } }
SimpleYacc.yacc
%{ // Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg public ProgrNode root; // Корневой узел синтаксического дерева public Parser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { } %} %output = SimpleYacc.cs %union { public double dVal; public int iVal; public string sVal; public Node nVal; public BlockNode blVal; public ProgrNode prVal; } %using System.IO; %using ProgramTree; %namespace SimpleParser %start progr %token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON %token <iVal> INTNUM %token <sVal> ID %type <nVal> expr assign st comp cycl ident %type <blVal> stlist comp %type <prVal> progr %% progr : stlist { root = new ProgrNode($1); } ; stlist : st { $$ = new BlockNode($1 as StatementNode); } | stlist SEMICOLON st { $1.Add($3 as StatementNode); $$ = $1; } ; st : assign { $$ = $1; } | comp { $$ = $1; } | cycl { $$ = $1; } ; ident : ID { $$ = new IdNode($1); } ; assign : ident ASSIGN expr { $$ = new AssignNode($1 as IdNode,$3 as ExprNode,0); } ; expr : ident { $$ = $1 as IdNode; } | INTNUM { $$ = new NumNode($1); } ; comp : BEGIN stlist END { $$ = $2; } ; cycl : CYCLE expr st { $$ = new CycleNode($2 as ExprNode,$3 as StatementNode); } ; %%