This shows you the differences between two versions of the page.
cpl-atm:laboratoare:laborator3 [2013/10/31 08:24] alexandru.radovici |
cpl-atm:laboratoare:laborator3 [2013/11/01 13:13] (current) laura.vasilescu [Exemplu] |
||
---|---|---|---|
Line 14: | Line 14: | ||
</code> | </code> | ||
+ | ===== Lexer ===== | ||
+ | <code> | ||
+ | npm install -g jison-lex | ||
+ | </code> | ||
+ | |||
+ | ===== Exemplu ===== | ||
+ | O să construim cu ajutorul unui lexer, un program simplu care calculează suma mai multor numere. | ||
+ | |||
+ | Pentru început, definim lexerul: | ||
+ | <code lex sum.lex> | ||
+ | %% | ||
+ | [0-9]+ return 'NUMBER'; | ||
+ | '+' return '+'; | ||
+ | ' '+ return 'SPACE'; | ||
+ | %% | ||
+ | </code> | ||
+ | |||
+ | Generăm un fișier js din acesta: | ||
+ | <code> | ||
+ | jison-lex sum.lex | ||
+ | </code> | ||
+ | |||
+ | Observăm că a apărut un nou fișier numit ''sum.js''. | ||
+ | |||
+ | Acest fișier trebuie modificat astfel: | ||
+ | * se șterge tot conținutul funcției ''parseError'' și se lasă doar ''throw new Error(str);'' | ||
+ | * la sfârșitul fișierului trebuie adăugată următoarea linie ''exports.nume_fisier = nume_fisier'', unde ''nume_fisier'' reprezintă numele fișierului anterior, fără extensie; în cazul nostru, ''sum''. | ||
+ | |||
+ | Construim programul de bază. Vom realiza un parser, folosindu-ne de lexerul anterior. | ||
+ | <code lex main.lex> | ||
+ | var lexer = require("./sum.js").sum; | ||
+ | lexer.setInput("10+12+1"); | ||
+ | |||
+ | |||
+ | function my_sum () | ||
+ | { | ||
+ | var sum = 0; | ||
+ | var i; | ||
+ | |||
+ | for (i = 0; i < tokens.length; i++) | ||
+ | if (tokens[i][0] == 'NUMBER') | ||
+ | sum = sum + tokens[i][1]; | ||
+ | |||
+ | console.log("Sum = " + sum); | ||
+ | } | ||
+ | |||
+ | |||
+ | var token; | ||
+ | var tokens = []; | ||
+ | do | ||
+ | { | ||
+ | token = lexer.lex(); | ||
+ | if (token != 'SPACE' && token != lexer.EOF) | ||
+ | tokens.push([token, parseInt(lexer.yytext)]); | ||
+ | } | ||
+ | while (token != lexer.EOF); | ||
+ | |||
+ | my_sum(); | ||
+ | |||
+ | </code> | ||
+ | |||
+ | == Exercițiu == | ||
+ | |||
+ | Construiți un lexer pentru următoarea gramatică: | ||
+ | <code> | ||
+ | xml: <ID parameters>xml</ID> | ||
+ | parameters: parameter parameters |; | ||
+ | parameter: ID = "TEXT" | ||
+ | TEXT: '{' ALFANUMERIC '}' | ||
+ | </code> | ||
+ | Realizați în js un parser pentru aceasta. | ||
+ | |||
+ | <hidden> | ||
+ | %% | ||
+ | |||
+ | [a-zA-Z][a-zA-Z0-9]* return 'ID'; | ||
+ | \{[a-zA-Z][a-zA-Z0-9]*\} return 'TEXT'; | ||
+ | ' '+ return 'SPACE'; | ||
+ | '<' return '<'; | ||
+ | '/' return '/'; | ||
+ | '>' return '>'; | ||
+ | '=' return '='; | ||
+ | '"' return '"'; | ||
+ | |||
+ | %% | ||
+ | |||
+ | text pentru input | ||
+ | <names ls="{lalala}">{fsdafsd}</names> | ||
+ | </hidden> |