parent
f9fea06e74
commit
1e4ad36f25
@ -1,91 +1,91 @@ |
|||||||
#include "parser.hpp" |
#include "parser.hpp" |
||||||
|
|
||||||
using namespace peglib; |
using namespace peglib; |
||||||
using namespace std; |
using namespace std; |
||||||
|
|
||||||
static auto g_grammar = R"( |
static auto g_grammar = R"( |
||||||
PROGRAM <- _ STATEMENTS |
PROGRAM <- _ STATEMENTS |
||||||
|
|
||||||
STATEMENTS <- EXPRESSION* |
STATEMENTS <- EXPRESSION* |
||||||
|
|
||||||
EXPRESSION <- ASSIGNMENT / PRIMARY |
EXPRESSION <- ASSIGNMENT / PRIMARY |
||||||
ASSIGNMENT <- IDENTIFIER '=' _ EXPRESSION |
ASSIGNMENT <- IDENTIFIER '=' _ EXPRESSION |
||||||
WHILE <- 'while' _ EXPRESSION BLOCK |
WHILE <- 'while' _ EXPRESSION BLOCK |
||||||
IF <- 'if' _ EXPRESSION BLOCK ('else' _ 'if' _ EXPRESSION BLOCK)* ('else' _ BLOCK)? |
IF <- 'if' _ EXPRESSION BLOCK ('else' _ 'if' _ EXPRESSION BLOCK)* ('else' _ BLOCK)? |
||||||
FUNCTION <- 'fn' _ PARAMETERS BLOCK |
FUNCTION <- 'fn' _ PARAMETERS BLOCK |
||||||
PARAMETERS <- '(' _ (IDENTIFIER (',' _ IDENTIFIER)*)? ')' _ |
PARAMETERS <- '(' _ (IDENTIFIER (',' _ IDENTIFIER)*)? ')' _ |
||||||
FUNCTION_CALL <- IDENTIFIER ARGUMENTS |
FUNCTION_CALL <- IDENTIFIER ARGUMENTS |
||||||
ARGUMENTS <- '(' _ (EXPRESSION (', ' _ EXPRESSION)*)? ')' _ |
ARGUMENTS <- '(' _ (EXPRESSION (', ' _ EXPRESSION)*)? ')' _ |
||||||
|
|
||||||
PRIMARY <- CONDITION (CONDITION_OPERATOR CONDITION)? |
PRIMARY <- CONDITION (CONDITION_OPERATOR CONDITION)? |
||||||
CONDITION <- TERM (TERM_OPERATOR TERM)* |
CONDITION <- TERM (TERM_OPERATOR TERM)* |
||||||
TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* |
TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* |
||||||
FACTOR <- WHILE / IF / FUNCTION / FUNCTION_CALL / NUMBER / BOOLEAN / STRING / INTERPOLATED_STRING / IDENTIFIER / '(' _ EXPRESSION ')' _ |
FACTOR <- WHILE / IF / FUNCTION / FUNCTION_CALL / NUMBER / BOOLEAN / STRING / INTERPOLATED_STRING / IDENTIFIER / '(' _ EXPRESSION ')' _ |
||||||
|
|
||||||
BLOCK <- '{' _ STATEMENTS '}' _ |
BLOCK <- '{' _ STATEMENTS '}' _ |
||||||
|
|
||||||
CONDITION_OPERATOR <- < ('==' / '!=' / '<=' / '<' / '>=' / '>') > _ |
CONDITION_OPERATOR <- < ('==' / '!=' / '<=' / '<' / '>=' / '>') > _ |
||||||
TERM_OPERATOR <- < [-+] > _ |
TERM_OPERATOR <- < [-+] > _ |
||||||
FACTOR_OPERATOR <- < [*/%] > _ |
FACTOR_OPERATOR <- < [*/%] > _ |
||||||
IDENTIFIER <- < [a-zA-Z_][a-zA-Z0-9_]* > _ |
IDENTIFIER <- < [a-zA-Z_][a-zA-Z0-9_]* > _ |
||||||
|
|
||||||
NUMBER <- < [0-9]+ > _ |
NUMBER <- < [0-9]+ > _ |
||||||
BOOLEAN <- < ('true' / 'false') > _ |
BOOLEAN <- < ('true' / 'false') > _ |
||||||
STRING <- ['] < (!['] .)* > ['] _ |
STRING <- ['] < (!['] .)* > ['] _ |
||||||
|
|
||||||
INTERPOLATED_STRING <- '"' ('{' _ EXPRESSION '}' / INTERPOLATED_CONTENT)* '"' _ |
INTERPOLATED_STRING <- '"' ('{' _ EXPRESSION '}' / INTERPOLATED_CONTENT)* '"' _ |
||||||
INTERPOLATED_CONTENT <- (!["{] .) (!["{] .)* |
INTERPOLATED_CONTENT <- (!["{] .) (!["{] .)* |
||||||
|
|
||||||
~_ <- (Space / EndOfLine / Comment)* |
~_ <- (Space / EndOfLine / Comment)* |
||||||
Space <- ' ' / '\t' |
Space <- ' ' / '\t' |
||||||
EndOfLine <- '\r\n' / '\n' / '\r' |
EndOfLine <- '\r\n' / '\n' / '\r' |
||||||
EndOfFile <- !. |
EndOfFile <- !. |
||||||
Comment <- '/*' (!'*/' .)* '*/' / ('#' / '//') (!(EndOfLine / EndOfFile) .)* (EndOfLine / EndOfFile)
|
Comment <- '/*' (!'*/' .)* '*/' / ('#' / '//') (!(EndOfLine / EndOfFile) .)* (EndOfLine / EndOfFile)
|
||||||
)"; |
)"; |
||||||
|
|
||||||
peg& get_parser() |
peg& get_parser() |
||||||
{ |
{ |
||||||
static peg parser; |
static peg parser; |
||||||
|
|
||||||
static bool initialized = false; |
static bool initialized = false; |
||||||
|
|
||||||
if (!initialized) { |
if (!initialized) { |
||||||
initialized = true; |
initialized = true; |
||||||
|
|
||||||
parser.log = [&](size_t ln, size_t col, const string& msg) { |
parser.log = [&](size_t ln, size_t col, const string& msg) { |
||||||
cerr << ln << ":" << col << ": " << msg << endl; |
cerr << ln << ":" << col << ": " << msg << endl; |
||||||
}; |
}; |
||||||
|
|
||||||
if (!parser.load_grammar(g_grammar)) { |
if (!parser.load_grammar(g_grammar)) { |
||||||
throw logic_error("invalid peg grammar"); |
throw logic_error("invalid peg grammar"); |
||||||
} |
} |
||||||
|
|
||||||
parser.ast({ |
parser.ast({ |
||||||
{ peg::AstNodeType::Regular, "STATEMENTS", Statements }, |
{ peg::AstNodeType::Regular, "STATEMENTS", Statements }, |
||||||
{ peg::AstNodeType::Regular, "WHILE", While }, |
{ peg::AstNodeType::Regular, "WHILE", While }, |
||||||
{ peg::AstNodeType::Regular, "ASSIGNMENT", Assignment }, |
{ peg::AstNodeType::Regular, "ASSIGNMENT", Assignment }, |
||||||
{ peg::AstNodeType::Regular, "IF", If }, |
{ peg::AstNodeType::Regular, "IF", If }, |
||||||
{ peg::AstNodeType::Regular, "FUNCTION", Function }, |
{ peg::AstNodeType::Regular, "FUNCTION", Function }, |
||||||
{ peg::AstNodeType::Regular, "PARAMETERS", Undefined }, |
{ peg::AstNodeType::Regular, "PARAMETERS", Undefined }, |
||||||
{ peg::AstNodeType::Regular, "FUNCTION_CALL", FunctionCall }, |
{ peg::AstNodeType::Regular, "FUNCTION_CALL", FunctionCall }, |
||||||
{ peg::AstNodeType::Regular, "ARGUMENTS", Undefined }, |
{ peg::AstNodeType::Regular, "ARGUMENTS", Undefined }, |
||||||
{ peg::AstNodeType::Optimizable, "PRIMARY", Condition }, |
{ peg::AstNodeType::Optimizable, "PRIMARY", Condition }, |
||||||
{ peg::AstNodeType::Optimizable, "CONDITION", BinExpresion }, |
{ peg::AstNodeType::Optimizable, "CONDITION", BinExpresion }, |
||||||
{ peg::AstNodeType::Optimizable, "TERM", BinExpresion }, |
{ peg::AstNodeType::Optimizable, "TERM", BinExpresion }, |
||||||
{ peg::AstNodeType::Token, "CONDITION_OPERATOR", Undefined }, |
{ peg::AstNodeType::Token, "CONDITION_OPERATOR", Undefined }, |
||||||
{ peg::AstNodeType::Token, "TERM_OPERATOR", Undefined }, |
{ peg::AstNodeType::Token, "TERM_OPERATOR", Undefined }, |
||||||
{ peg::AstNodeType::Token, "FACTOR_OPERATOR", Undefined }, |
{ peg::AstNodeType::Token, "FACTOR_OPERATOR", Undefined }, |
||||||
{ peg::AstNodeType::Token, "NUMBER", Number }, |
{ peg::AstNodeType::Token, "NUMBER", Number }, |
||||||
{ peg::AstNodeType::Token, "BOOLEAN", Boolean }, |
{ peg::AstNodeType::Token, "BOOLEAN", Boolean }, |
||||||
{ peg::AstNodeType::Token, "STRING", Undefined }, |
{ peg::AstNodeType::Token, "STRING", Undefined }, |
||||||
{ peg::AstNodeType::Token, "IDENTIFIER", Identifier }, |
{ peg::AstNodeType::Token, "IDENTIFIER", Identifier }, |
||||||
{ peg::AstNodeType::Regular, "INTERPOLATED_STRING", InterpolatedString }, |
{ peg::AstNodeType::Regular, "INTERPOLATED_STRING", InterpolatedString }, |
||||||
{ peg::AstNodeType::Token, "INTERPOLATED_CONTENT", Undefined }, |
{ peg::AstNodeType::Token, "INTERPOLATED_CONTENT", Undefined }, |
||||||
}, |
}, |
||||||
Undefined); |
Undefined); |
||||||
} |
} |
||||||
|
|
||||||
return parser; |
return parser; |
||||||
} |
} |
||||||
|
|
||||||
// vim: et ts=4 sw=4 cin cino={1s ff=unix
|
// vim: et ts=4 sw=4 cin cino={1s ff=unix
|
||||||
|
Loading…
Reference in new issue